/* FederatedSearchController
   by: Scott Jorgensen (sjorgensen@salesforce.com)
   
   Queries multiple systems and collates the results for display in Visualforce
*/

public class FederatedSearchController { 
        
        /* Instance Variables */
        public static Boolean testMode = false;
        
        // search variables
        public List<Case> caseResults { get; private set; }
        public List<Solution> solutionResults { get; private set; }
        public List<Document> documentResults { get; private set; }
        public List<YahooSearch> yahooResults { get; private set; }

        public Integer numCaseResults { get{ return caseResults.size();} private set; }
        public Integer numSolutionResults { get{ return solutionResults.size();} private set; }
        public Integer numDocumentResults { get{ return documentResults.size();} private set; }
        public Integer numYahooResults { get{ return yahooResults.size();} private set; }
        public Boolean getNoResults() { return (0 == numCaseResults+numSolutionResults+numDocumentResults+numYahooResults); }

        public String keywords { public get; set; }
        public Boolean showResults { get; private set; }
        
        // bookmark variables
        private final String BASE_URL = 'https://na1.salesforce.com' + Page.federatedSearch.getURL();
        public String bookmarkURL { get; private set; }
        public Boolean showBookmarkMessage { get; private set; } 
        
        String yahooURL = 'http://search.yahooapis.com/WebSearchService/V1/webSearch';
        String appid = '7.zX80HV34Fh.Mapw46SoYG8e_jQcBYgrbY1DC9aT1uw.E7VID8L4._B_4ER_dihckwMohY-';
        String query = 'salesforce.com';        

        /* Constructor */ 
        
        public FederatedSearchController() { 

                caseResults = new List<Case>();
                solutionResults = new List<Solution>();
                documentResults = new List<Document>();
                yahooResults = new List<YahooSearch>();
                
                showResults = false;
                showBookmarkMessage = false;
                bookmarkURL = BASE_URL + '?';
        
                pullQuerySearchParametersIntoModel();
        }
        
        /* Instance Methods */
        
        public PageReference link() {   
                showBookmarkMessage = true;     
                return null;
        }
        
        public PageReference doSearch() {               
                showBookmarkMessage = false;
                updateBookmarkUrl();
                                
                //If there are no keywords or filters then bail out
                if(     keywords == null || keywords.length() < 1 )  {
                                return null; 
                }
                
                if(testMode) 
                        return null;
                else
                return executeCallout();
        }
        private PageReference executeCallout() {
                // Yahoo Web Search
            // Get the XML document from the external server
                HttpRequest req = new HttpRequest();
            req.setEndpoint(yahooURL+'?appid='+appid+'&query='+EncodingUtil.urlEncode(keywords, 'UTF-8'));
            req.setMethod('GET');
            HttpResponse response = new Http().send(req);
            System.debug(response.getBody());
                XmlStreamReader reader = response.getXmlStreamReader();

                yahooResults = new List<YahooSearch>();
                
            // Read through the XML
            while(reader.hasNext()) {
                        System.debug('Event Type:' + reader.getEventType());
                        if (reader.getEventType() == XmlTag.START_ELEMENT) {
                                System.debug(reader.getLocalName());
                    if ('Result' == reader.getLocalName()) {
                        yahooResults.add(new YahooSearch(reader)); 
                    }
                        }
                        reader.next();
            }
            return continueProcessing();
        }
        public PageReference continueProcessing() {
                                
                // Salesforce.com Search
                List<List<SObject>> results = [find :keywords returning Case, Solution, Document];
                caseResults = [select id, CaseNumber, Subject, Status from Case where id in :(List<Case>)results[0]];
                solutionResults = [select id, SolutionName from Solution where id in :(List<Solution>)results[1]];
                documentResults = [select id, Name from Document where id in :(List<Document>)results[2]];
                
                showResults = true;
                
                return null;
        }

        
        // Checks URL for query parameters, perform search if necessary
        // Needed for bookmarking
        private void pullQuerySearchParametersIntoModel() {
                if(System.currentPageReference().getParameters().get('keywords') != null) {
                        keywords = EncodingUtil.urlDecode(System.currentPageReference().getParameters().get('keywords'),'UTF-8'); 
                        showResults = true;
                }
                if(showResults) {doSearch();}
        }
        
        private void updateBookmarkUrl() {
                bookmarkURL = BASE_URL + '?';
                
                if(keywords != null && keywords.length() > 1) {
                        bookmarkURL += 'keywords='+EncodingUtil.urlEncode(keywords,'UTF-8'); 
                }
        }
}